package com.nuanshui.framework.utils.ssdb;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.nutz.ssdb4j.SSDBs;
import org.nutz.ssdb4j.spi.Response;
import org.nutz.ssdb4j.spi.SSDB;
import org.sword.wechat4j.user.User;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;

public class SSDBUtil {

	private final  SSDB ssdb;
	
	public SSDBUtil(final String host, final int port, final int timeout) {
		 ssdb =  SSDBs.pool(host,port,timeout,null);
	}
	

	public void zaddObj(String key,long score,Object obj) {
		try {
			ssdb.hset(key,score, JSON.toJSONString(obj)); 
			
		} catch (Exception e) {
		   e.printStackTrace();
		}
		   
    }
   
   /**
    * 获取大于score的所有数据
    * @param @param key
    * @param @param score
    * @param @param clazz
    * @param @return
    * @author guohao
    * @date 2016年5月12日 上午9:55:19
    * @since $
    */
   public <T extends Object> List<T> zrangByMinScore(String key,long score,Class<T> clazz) {
   	   int limit = ssdb.hsize(key).asInt();
	   Response response =  ssdb.hrscan(key, "",score+1, limit);
	   Map<String,String> map =  response.mapString();
	   List<T> list = new ArrayList<T>();
	   for(Entry<String,String> e :map.entrySet()) {
		   list.add(JSON.parseObject(e.getValue(),clazz));
	   }
	   return list;
   }
   
   public <T extends Object> List<T> zrangByMaxcore(String key,long score,Class<T> clazz,int offset,int size) {
	   Response response =  ssdb.hrscan(key,score,"",offset+size);
	   LinkedHashMap<String,String> map =  (LinkedHashMap<String, String>) response.mapString();
	   System.out.println(offset+size);
	   System.out.println(offset);
	   List<T> list = new ArrayList<T>();
	   int i = 0;
	   System.out.println(map.entrySet().size());
	   for(Entry<String,String> e :map.entrySet()) {
		   if(i<offset-1) {
			   i++;
			   continue;
		   }
		   list.add(JSON.parseObject(e.getValue(),clazz));
		   i++;
	   }
	   return list;
   }
   
   /**
    * list 头部插入
    * @param 
    * @author guohao
    * @date 2015年6月2日 上午11:31:07
    */
   public void lpush(final String key,Collection<Object> objs) {
	   for(Object obj :objs) {
		   ssdb.qpush_front(key,JSON.toJSONString(obj));
       } 
   }
   
   public void rpush(final String key,Collection<Object> objs) {
	   for(Object obj :objs) {
		   ssdb.qpush(key,JSON.toJSONString(obj));
       } 
   }
   
   public void rpush(final String key,Object obj) {
	  
		ssdb.qpush(key,JSON.toJSONString(obj));
       
   }
   
   
   public void lpush(final String key,Object obj) {
	   
	   ssdb.qpush_front(key,JSON.toJSONString(obj));
   }
   
   public List<String> lrangeAll(String key) {
   	
	   long len = this.llen(key);
	   Response response = ssdb.qrange(key, 0, (int)len);
	   return response.listString();
   }
   
   public List<String> rrangeAll(String key) {
	   	
	   long len = this.llen(key);
	   Response response = ssdb.qrange(key, 0,(int)len);
	   List<String> result = response.listString();
	   return Lists.reverse(result);
   }
   
   public void lclear(String key) {
	   
	   ssdb.qclear(key);
	   
   }
   
   public void lset(final String key,Integer index,Object obj) { 
	   ssdb.qset(key, index, JSON.toJSONString(obj));
   }  
   
   public Long llen(String key) {
  	  return ssdb.qsize(key).asLong();
   }
  
   
   
   public void set(final String key, String value) {
       ssdb.set(key, value);
   }
   
   public String get(String key) {
	   Response response = ssdb.get(key);
	   if(response.notFound()) return "";
	   return response.asString();
   }
   
   /**
    * 保存对象并设置失效时间 
    * @param @param key
    * @param @param value
    * @param @param ttl 存活时间单位为秒
    * @author guohao
    * @date 2016年8月11日 下午3:43:01
    * @since $
    */
   public void setex(final String key,String value,int ttl) {
	   ssdb.setx(key, value, ttl);
   }
   
   /**
    * 获取key的还有的生存时间 (如果返回-1表示这个key不存在 如果返回  -2 表示这个key没有过期时间)
    * @param @param key
    * @param @return
    * @author guohao
    * @date 2016年8月11日 下午3:45:29
    * @since $
    */
   public long ttl(String key) {
	   Response response =  ssdb.ttl(key);
	   
	   long time  = response.asLong();
	   
	   if(time == -1) {
		  if(this.exists(key)) return -2;
	   }
	   return time;
	   
	   
   }
   
   /**
    * 删除某个key
    * @param @param key
    * @author guohao
    * @date 2016年8月11日 下午3:56:29
    * @since $
    */
   public void del(String key) {
	    ssdb.del(key);
   }
   
   /**
    * 设置数据的长度(一个汉字占三个字节)
    * @param @param key
    * @param @return
    * @author guohao
    * @date 2016年8月11日 下午4:17:05
    * @since $
    */
   public long  strlen(String key){
	   
	   Response response = ssdb.strlen(key);
	   if(response.notFound()) return -1;
	   return response.asLong();
   }
   
   /**
    * 获取某个 key的值，并设置新的值
    * @param @param key
    * @param @param value
    * @param @return
    * @author guohao
    * @date 2016年8月11日 下午4:16:47
    * @since $
    */
   public String getSet(String key,String value) {
	   Response response = ssdb.getset(key,value);
	   if(response.notFound()) return "";
	   return response.asString();
	   
   }
   
   /**
    * 判断某个key是否存在
    * @param @param key
    * @param @return
    * @author guohao
    * @date 2016年8月11日 下午3:56:06
    * @since $
    */
   public boolean exists(String key) {
	   Response response = ssdb.exists(key);
	  long result = response.asLong();
       return result == 1;
   }
   
   
   public void hset(String mapKey,String hkey,Object hvalue) {
	   ssdb.hset(mapKey, hkey, JSON.toJSONString(hvalue));
   }
   
   public <T extends Object> T hget(final String mapKey,String hkey,Class<T> clazz) { 
	   Response response = ssdb.hget(mapKey, hkey);
	   if(response.notFound()) return null;
	   return JSON.parseObject(response.asString(), clazz);
	   
   }
   
   public void hdel(String mapKey,String hkey) {
	   ssdb.hdel(mapKey, hkey);
   }
   
   public boolean hexists(String mapKey,String hkey) {
	  Response response =  ssdb.hexists(mapKey, hkey);
	  long result = response.asLong();
	  System.out.println(result);
       return result > 0;

   }
   
   public long hsize(String mapKey) {
	   
	   return ssdb.hsize(mapKey).asLong();
   }
   
   
   
   public long incr(String key) {
	    return ssdb.incr(key, 1).asLong();
   }
   
   public long decr(String key){
	    return ssdb.decr(key,1).asLong();
   }
   
   
   
   
   
   
   public static void main(String[] args) {
	   User user = new User();
	   user.setCity("ceshi");
	   User user2 = new User();
	   user2.setCity("hao");
	   
	  SSDBUtil ssdb = new SSDBUtil("10.0.0.254",6388, 3000);
	  System.out.println(ssdb.decr("test01"));
	  //System.out.println(ssdb.get("name"));
   }
   
   public <V extends Object> HashMap<String, V> hgetAll(String mapKey,Class<V> clazz) {
	   
	  Response response   =   ssdb.hgetall(mapKey);
	  Map<String, Object> map =   response.map();
	  
	 HashMap<String, V> result = new HashMap<>();
	 
	 for(String key :map.keySet()) {
		 Object object = map.get(key);
		 System.out.println(object.getClass());
		// result.put(key, JSON.parseObject(, clazz));
	 }
	 return result;
	  
	   
   }
   
   
   @SuppressWarnings("unused")
private static void  printList(List<String> list) {
	   for(String str :list) {
		   System.out.println(str);
	   }
   }
	
	
	
}
